home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 276-300 / 285 / liner / source / yafr / yafr.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  14KB  |  460 lines

  1. /*- - - - - - - - - - YAFR - Yet Another File Requester - - - - - - - - -*/
  2. /*- - - - - - - - - - - - - - Version  1.10 - - - - - - - - - - - - - - -*/
  3. /*YAFR V1.1 Copyright ©1989 by Dave  Schreiber.  All rights reserved.    */
  4. /*YAFR may be freely distributed, but may not be sold.  Exceptions to    */
  5. /*are reasonable copying, media, and shipping fees.  This copyright      */
  6. /*message must be included (including when YAFR is used as a part of     */
  7. /*another program).                                                      */
  8.  
  9. /*Compiled under Lattice C V5.02                                         */
  10. /*Command line:  1> lc -cw -j30 yafr                                     */
  11. /*Generates YAFR.o which is linked into the host program                 */
  12. /*You must assign YAFR: to the directory where the YAFR source is stored */
  13.  
  14. /*If you have any comments, suggestions, etc. I can be reached at:       */
  15. /*Dave Schreiber                                                         */
  16. /*1234 Collins Lane                                                      */
  17. /*San Jose, CA   95129-4208                                              */
  18. /*Usenet:  davids@ucscb.ucsc.edu (during the school year)                */
  19.  
  20.  
  21. #include <YAFR:yafrHead.h>
  22.              /*^^^^system includes, structure definitions, etc.*/
  23. #define CRNT header.current->fib
  24.  
  25. /*Parameters are:  fn-string for filename (33 characters)                */
  26. /*dn-string for directory name (150 characters)                          */
  27. /*en-string for filename extension (.c, .pic, etc. 18 characters)        */
  28. /*cn-string for combined directory and filename (183 characters)         */
  29. /*(NULL if you don't want the combined filename)                         */
  30. /*X,Y-YAFR's window's X,Y location (relative to the screen               */
  31. /*wn-text for YAFR's window's title bar                                  */
  32. /*scr-Pointer to screen that window should appear on (NULL for           */
  33. /*Workbench) filepen-Pen color that filenames should be displayed in     */
  34. /*dirpen-Pen color that directory names should be displayed in           */
  35. /*DisableInfo-Boolean; TRUE-files ending in .info aren't displayed       */
  36. /*                     FALSE-.info files are displayed                   */
  37.  
  38. /*Version 1.1, completed October 30, 1989*/
  39. /*Directory and filename string gadgets now auto-activate and appropriate*/
  40. /*times.  A bug that caused an incorrect filename to be returned when the*/
  41. /*user pressed CANCEL has been fixed                                     */
  42.  
  43. GetFilename(fn,dn,en,cn,X,Y,wn,scr,filepen,dirpen,DisableInfo)
  44. char *fn,*dn,*en,*cn,*wn;
  45. USHORT X,Y,filepen,dirpen;
  46. BYTE DisableInfo;
  47. struct Screen *scr;
  48. {
  49.    int status=GN_NEWDIR;
  50.    struct FileLock *DirLock;
  51.  
  52.    if(DisableInfo)
  53.       yf_Info.Flags|=SELECTED;
  54.    else
  55.       yf_Info.Flags=GADGHIMAGE|GADGIMAGE;
  56.  
  57.    yafr_e_FilenamePenColor = filepen;
  58.    yafr_e_DirnamePenColor = dirpen;
  59.    DirLock=(struct FileLock *)Lock(dn,ACCESS_READ);
  60.  
  61.    strcpy(yf_DirNameSIBuff,dn);
  62.    strcpy(yf_ExtNameSIBuff,en);
  63.    strcpy(yf_filenameSIBuff,fn);
  64.    NewFNWindow.LeftEdge=X;
  65.    NewFNWindow.TopEdge=Y;
  66.    NewFNWindow.Title=(char *)wn;
  67.    NewFNWindow.Screen=(struct Screen *) scr;
  68.    NewFNWindow.Type= (scr) ? CUSTOMSCREEN : WBENCHSCREEN;
  69.  
  70.    if((FNWindow=(struct Window *)OpenWindow(&NewFNWindow))==NULL)
  71.       {
  72.       UnLock(DirLock);
  73.       return(FALSE);
  74.       }
  75.    SetWindowTitles(FNWindow,-1,"YAFR V1.10 ©1989 by Dave Schreiber");
  76.    SetAPen(FNWindow->RPort,1);
  77.    Move(FNWindow->RPort,6,19);
  78.    Text(FNWindow->RPort,"Directory",9);
  79.    Move(FNWindow->RPort,6,154);
  80.    Text(FNWindow->RPort,"Extension",9);
  81.    Move(FNWindow->RPort,6,165);
  82.    Text(FNWindow->RPort,"Filename",8);
  83.  
  84.    ActivateGadget(&yf_DirName,FNWindow,NULL);
  85.    while((status = yf_GetName(DirLock)) == GN_NEWDIR)
  86.       {
  87.       UnLock(DirLock);
  88.       DirLock=(struct FileLock *)Lock(yf_DirNameSIBuff,ACCESS_READ);
  89.       ActivateGadget(&yf_filename,FNWindow,NULL);
  90.       }
  91.  
  92.    UnLock(DirLock);
  93.    if(status)
  94.    {
  95.       strcpy(fn,yf_filenameSIBuff);
  96.       strcpy(dn,yf_DirNameSIBuff);
  97.       strcpy(en,yf_ExtNameSIBuff);
  98.       if(cn)
  99.       {
  100.          strcpy(cn,yf_DirNameSIBuff);
  101.          if( (dn[strlen(dn)-1] != ':') && strlen(dn) )
  102.             strcat(cn,"/");
  103.          strcat(cn,yf_filenameSIBuff);
  104.       }
  105.    }
  106.  
  107.    CloseWindow(FNWindow);
  108.    return(status);
  109. }
  110.  
  111. yf_GetName(Lock)
  112. struct FileLock *Lock;
  113. {
  114.    struct fibHeader header;
  115.    int status3,status2,status;
  116.    USHORT FNNumber=0;
  117.  
  118.    header.first=header.directory=NULL;
  119.    if(yf_GetFib(&header)==FALSE)
  120.       return(FALSE);
  121.    yf_SliderSInfo.VertPot=0;
  122.    yf_UpdateSlider(1,&yf_SliderSInfo,&yf_Slider);
  123.    yf_ClearFileBox();
  124.    if(!yf_ispipedevice(yf_DirNameSIBuff)) /*Check for pipe: device*/
  125.       if(Lock!=NULL)
  126.          {
  127.          Examine(Lock,&(CRNT));
  128.          if(yf_GetFib(&header)==FALSE)  /*Get next node*/
  129.             return(NULL);
  130.          while((status3=ExNext(Lock,&(CRNT))))
  131.             {
  132.             if((status2=((yf_CheckExt(CRNT.fib_FileName,yf_ExtNameSIBuff) ||
  133.                   CRNT.fib_DirEntryType > 0) &&
  134.                   yf_CheckInfo(CRNT.fib_FileName)) ))
  135.                {
  136.                if(FNNumber<10)
  137.                   yf_PrintFileName(&(CRNT),Rp,XBorder,YBorder+(10*FNNumber++));
  138.                else
  139.                   yf_UpdateSlider(++FNNumber,&yf_SliderSInfo,&yf_Slider);
  140.                }
  141.             while((status=yf_CheckIntuiMessages(FNNumber,&header))!=GN_DONE)
  142.                {
  143.                if(status==GN_PARENT)
  144.                   {
  145.                   yf_Parentize(yf_DirNameSIBuff);
  146.                   yf_RefreshGadget(&yf_DirName,FNWindow,NULL);
  147.                   yf_FreeFuncMemory(header.directory);
  148.                   return(GN_NEWDIR);
  149.                   }
  150.                if(status < GN_PARENT)
  151.                   {
  152.                   yf_FreeFuncMemory(header.directory);
  153.                   return(status);   /*For OK,NEWDIR, & CANCEL*/
  154.                   }
  155.                }
  156.             if(status2)
  157.                if(yf_GetFib(&header)==FALSE)
  158.                   return(NULL);
  159.             }
  160.             header.current->prev->next=NULL;
  161.             if(header.directory->next == header.current) /*If no files*/
  162.                header.directory->next=header.first=header.last=
  163.                      header.top=NULL;     /*NULL certain pointers*/
  164.             FreeMem(header.current,sizeof(struct fibNode));
  165.          }
  166.    for(;;)  /*FOREVER*/
  167.       {
  168.       Wait(1<<FNWindow->UserPort->mp_SigBit);
  169.       while((status=yf_CheckIntuiMessages(FNNumber,&header))!=GN_DONE)
  170.          {
  171.          if(status==GN_PARENT)
  172.             if(yf_Parentize(yf_DirNameSIBuff))
  173.                {
  174.                yf_RefreshGadget(&yf_DirName,FNWindow,NULL);
  175.                yf_FreeFuncMemory(header.directory);
  176.                return(GN_NEWDIR);
  177.                }
  178.          if(status < GN_PARENT)
  179.             {
  180.             yf_FreeFuncMemory(header.directory);
  181.             return(status);   /*For OK,NEWDIR, & CANCEL*/
  182.             }
  183.          }
  184.       }
  185. }
  186.  
  187. yf_CheckInfo(name)  /*Check to see if .info's should be printed*/
  188. char *name;
  189. {
  190.    if(!(yf_Info.Flags & SELECTED))
  191.       return(TRUE);
  192.  
  193.    return(!(strcmp(&name[strlen(name)-5],".info")==0));
  194. }
  195.  
  196. yf_ClearFileBox()
  197. {
  198.    SetAPen(Rp,0);
  199.    RectFill(Rp,XBorder,YBorder-6,(25*8)+XBorder,YBorder+(100)-4);
  200.    SetAPen(Rp,1);
  201. }
  202.  
  203. yf_Parentize(str)
  204. char *str;
  205. {
  206.    int c;
  207.  
  208.    if(str[strlen(str)-1]==':')
  209.       return(FALSE);
  210.    for(c=strlen(str)-1;c >= 0;c--)
  211.       if(str[c]=='/')
  212.          {
  213.          str[c]=NULL;
  214.          c=0;
  215.          }
  216.       else
  217.          if(str[c]==':')
  218.             {
  219.             str[c+1]=NULL;
  220.             c=0;
  221.             }
  222.    return(TRUE);
  223. }
  224.  
  225. yf_UpdateSlider(Amt,Info,Gadgt)
  226. USHORT Amt;
  227. struct PropInfo *Info;
  228. struct Gadget *Gadgt;
  229. {
  230.    Info->VertBody=((0xFFFF*10)/Amt);
  231.    RefreshGadgets(Gadgt,FNWindow,NULL);
  232. }
  233.  
  234. yf_CheckIntuiMessages(Max,header)
  235. USHORT Max;
  236. struct fibHeader *header;
  237. {
  238.    struct fibNode *cur;
  239.    UBYTE c,line;
  240.    struct IntuiMessage *mesg;
  241.    struct Gadget *InUse;
  242.    ULONG Class;
  243.    USHORT Code;
  244.    SHORT X,Y;
  245.  
  246.    while((mesg=(struct IntuiMessage *)GetMsg(FNWindow->UserPort))!=NULL)
  247.       {
  248.       InUse=(struct Gadget *)mesg->IAddress;
  249.       X=mesg->MouseX;
  250.       Y=mesg->MouseY;
  251.       Class=mesg->Class;
  252.       Code=mesg->Code;
  253.       ReplyMsg(mesg);
  254.       switch(Class)
  255.          {
  256.          case MOUSEMOVE:
  257.             if(Max > 10)
  258.                yf_UpdateList(yf_SliderSInfo.VertPot,Max,header);
  259.             break;
  260.          case GADGETUP:
  261.             if(InUse->GadgetID <= 10)
  262.                {
  263.                strcpy(yf_DirNameSIBuff,InUse->GadgetText->IText);
  264.                yf_RefreshGadget(&yf_DirName,FNWindow,NULL);
  265.                return(GN_NEWDIR);
  266.                }
  267.             switch(InUse->GadgetID)
  268.                {
  269.                case 14:
  270.                   return(GN_CANCEL);
  271.                case 12:
  272.                case 13:
  273.                   return(GN_OK);
  274.                case 15:
  275.                   return(GN_PARENT);
  276.                case 11:
  277.                case 18:
  278.                   return(GN_NEWDIR);
  279.                }
  280.             return(GN_RIEN);     /*Nothing important*/
  281.             break;
  282.          case GADGETDOWN:
  283.          if(InUse->GadgetID == 18)
  284.             return(GN_NEWDIR);
  285.  
  286.          if((strcmp(yf_DirNameSIBuff,"PIPE:")!=0) &&  /*Don't try & get files*/
  287.           (strcmp(yf_DirNameSIBuff,"pipe:")!=0) && /*from PIPE: (most combos*/
  288.           (strcmp(yf_DirNameSIBuff,"Pipe:") != 0)) /*of upper & lower case)*/
  289.             {
  290.             line=(Y-YBorder+7)/10;    /*Get line clicked on*/
  291.             for(c=0,cur=(struct fibNode *)header->top;c!=line && cur!=NULL;c++)
  292.                cur=(struct fibNode *)cur->next;
  293.             if(cur != NULL)
  294.                if(cur->fib.fib_DirEntryType > 0)
  295.                   {
  296.                   if(yf_DirNameSIBuff[strlen(yf_DirNameSIBuff)-1] != ':')
  297.                      strcat(yf_DirNameSIBuff,"/");
  298.                   strcat(yf_DirNameSIBuff,cur->fib.fib_FileName);
  299.                   yf_RefreshGadget(&yf_DirName,FNWindow,NULL);
  300.                   return(GN_NEWDIR);
  301.                   }
  302.                else   /*Filename clicked upon*/
  303.                   {
  304.                   strcpy(yf_filenameSIBuff,cur->fib.fib_FileName);
  305.                   yf_RefreshGadget(&yf_filename,FNWindow,NULL);
  306.                   }
  307.             }
  308.          }
  309.       }
  310.    return(GN_DONE);
  311. }
  312.  
  313. yf_UpdateList(Pos,Num,header)
  314. USHORT Pos;
  315. USHORT Num;
  316. struct fibHeader *header;
  317. {
  318.    static USHORT LastFirstItem=30000;
  319.    ULONG FirstItem;
  320.    FirstItem=((Pos)*(Num-10)) >> 16 ;
  321.  
  322.    if( FirstItem != LastFirstItem)
  323.       yf_RewriteList(FirstItem,header);
  324.    LastFirstItem=FirstItem;
  325. }
  326.  
  327. yf_RewriteList(First,header)
  328. USHORT First;
  329. struct fibHeader *header;
  330. {
  331.    register struct fibNode *node;
  332.    register USHORT c,Y;
  333.  
  334.    if(First)
  335.       for(c=0,node=(struct fibNode *)header->first;c <= First;c++)
  336.          node=(struct fibNode *)node->next;
  337.    else
  338.       node=(struct fibNode *)header->first;
  339.    header->top=(struct fibNode *)node;
  340.    for(c=0,Y=YBorder;(c < 10) && (node!=NULL);
  341.          c++,Y+=10,node=(struct fibNode *)node->next)
  342.       yf_PrintFileName(&(node->fib),Rp,XBorder,Y);
  343. }
  344.  
  345. yf_CheckExt(name,ext)
  346. char *name,*ext;
  347. {
  348.    if(strlen(name) >= strlen(ext))
  349.       if(strcmp(&name[strlen(name)-strlen(ext)],ext)==0)
  350.          return(TRUE);
  351.    return(FALSE);
  352. }
  353.  
  354. yf_GetFib(header)
  355. struct fibHeader *header;
  356. {
  357.    header->last=(struct fibNode *)header->current;
  358.    if((header->current=(struct fibNode *)
  359.          AllocMem(sizeof(struct fibNode),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  360.       {
  361.       yf_FreeFuncMemory(header->current);
  362.       return(FALSE);
  363.       }
  364.    if(header->directory==NULL)
  365.       header->directory=(struct fibNode *)header->current;
  366.    else
  367.       {
  368.       if(header->first==NULL)
  369.          {
  370.          header->directory->next=header->first=header->last=header->top=
  371.                (struct fibNode *)header->current;
  372.          yf_CopyFIB(&(header->directory->fib),&(header->current->fib));
  373.          }
  374.       else
  375.          {
  376.          yf_CopyFIB(&(header->last->fib),&(header->current->fib));
  377.          header->last->next=(struct fibNode *)header->current;
  378.          header->current->prev=(struct fibNode *)header->last;
  379.          }
  380.       }
  381.    return(TRUE);
  382. }
  383.  
  384. yf_CopyFIB(from,to)
  385. struct FileInfoBlock *from,*to;
  386. {
  387.    to->fib_DiskKey=from->fib_DiskKey;
  388.    to->fib_DirEntryType=from->fib_DirEntryType;
  389.    to->fib_Protection=from->fib_Protection;
  390.    to->fib_EntryType=from->fib_EntryType;
  391.    to->fib_Size=from->fib_Size;
  392.    to->fib_NumBlocks=from->fib_NumBlocks;
  393.    strcpy(to->fib_FileName,from->fib_FileName);
  394.    strcpy(to->fib_Comment,from->fib_Comment);
  395.    to->fib_Date.ds_Days=from->fib_Date.ds_Days;
  396.    to->fib_Date.ds_Minute=from->fib_Date.ds_Minute;
  397.    to->fib_Date.ds_Tick=from->fib_Date.ds_Tick;
  398.  
  399.    return(TRUE);
  400. }
  401.  
  402. yf_PrintFileName(fib,RPrt,X,Y)
  403. struct FileInfoBlock *fib;
  404. struct RPort *RPrt;
  405. USHORT X,Y;
  406. {
  407.    UWORD len;
  408.    if(fib->fib_DirEntryType > 0)
  409.       SetAPen(RPrt,yafr_e_DirnamePenColor);
  410.    else
  411.       SetAPen(RPrt,yafr_e_FilenamePenColor);
  412.    Move(RPrt,X,Y);
  413.    Text(RPrt,"                         ",25);
  414.    Move(RPrt,X,Y);
  415.    len = (strlen(fib->fib_FileName)<=25) ? strlen(fib->fib_FileName) : 25;
  416.    Text(RPrt,fib->fib_FileName,len);
  417.    if(fib->fib_DirEntryType > 0)
  418.       Text(RPrt,"  (dir)",7);
  419. }
  420.  
  421. yf_RefreshGadget(Gadg,Wdw,Req)
  422. struct Gadget *Gadg;
  423. struct Window *Wdw;
  424. struct Req *Req;
  425. {
  426.    struct Gadget *next;
  427.    next=(struct Gadget *)Gadg->NextGadget;
  428.    Gadg->NextGadget=NULL;
  429.    RefreshGadgets(Gadg,Wdw,Req);
  430.    Gadg->NextGadget=(struct Gadget *)next;
  431.    return(TRUE);
  432. }
  433.  
  434. yf_FreeFuncMemory(first)   /*Free a fib list*/
  435. register struct fibNode *first;
  436. {
  437.    register struct fibNode *next,*current;
  438.    next=(struct fibNode *)first->next;
  439.    FreeMem(first,sizeof(struct fibNode));
  440.    while((current=(struct fibNode *)next)!=NULL)
  441.       {
  442.       next=(struct fibNode *)current->next;
  443.       FreeMem(current,sizeof(struct fibNode));
  444.       }
  445. }
  446.  
  447. yf_ispipedevice(device) /*Checks to see if the device is the PIPE:*/
  448. char *device;
  449. {
  450.    char temp[6];
  451.    int c;
  452.    for(c=0;c<5;c++) /*Convert weird capitalization (pIPe:) to pipe:*/
  453.       temp[c]=tolower(device[c]); /*So as to make it easy to check*/
  454.    temp[5]=NULL;
  455.    if(strcmp(device,"pipe:")==0)
  456.       return(TRUE);
  457.    else
  458.       return(FALSE);  
  459. }
  460.